package com.azdebugit.processor.test;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.util.DaemonThreadFactory;

/**
 * 订单回调入口
 *
 * @version OrderCallBackMain.java, v 0.1 2018-12-25 21:39
 */
public class OrderCallBackMain {

    /**
     * ring buffer的大小必须设置为2的指数倍，主要是为了将求模运算转为&运算提高效率
     */
    static int RING_BUFFER_SIZE = 1024;

    public static void main(String[] args) throws InterruptedException {
        // 订单事件工厂,用于预创建订单事件
        OrderCallBackFactory orderCallBackFactory = new OrderCallBackFactory();

        // 初始化disruptor
        // orderCallBackFactory: 事件工厂
        // RING_BUFFER_SIZE: 环形队列的大小,必须是2的指数倍
        // DaemonThreadFactory.INSTANCE: 线程工厂, disruptor会通过线程工程来创建消费者线程,默认每个消费者只会创建一个消费者线程
        // 
        Disruptor<OrderCallBackEvent> disruptor = new Disruptor<>(orderCallBackFactory, RING_BUFFER_SIZE, DaemonThreadFactory.INSTANCE, ProducerType.MULTI, new BlockingWaitStrategy());

        // disruptor默认支持广播模式,即同一个消息,所有注册的消费者都会消费一次
        // 注册开放平台回调处、注册微信吸粉微信吸粉
        disruptor.handleEventsWith(new OpenNotifiyHandle(), new WxFansHandle());

        // 启动disruptor
        disruptor.start();
        System.out.println("---↓↓↓↓↓↓↓↓↓↓↓↓↓1↓↓↓↓↓↓↓↓↓↓↓--");
        // 发布订单事件
        // disruptor会通过我们设置的事件工厂预先帮我创建好事件对象
        // 所以我们在发布事件时只需要为我们的event对象写入数据
        disruptor.publishEvent((event, sequence) -> {
            event.setOrderSn("----------------123456");
        });
        System.out.println("---↓↓↓↓↓↓↓↓↓↓↓↓↓2↓↓↓↓↓↓↓↓↓↓↓--");
        // 发布订单事件
        disruptor.publishEvent((event, sequence) -> {
            event.setOrderSn("---------------------9999");
        });
        System.out.println("---↓↓↓↓↓↓↓↓↓↓↓↓↓3↓↓↓↓↓↓↓↓↓↓↓--");
        // 另一种发布事件的方式，与上面的方式等价
        RingBuffer<OrderCallBackEvent> ringBuffer = disruptor.getRingBuffer();
        long sequence = ringBuffer.next();
        OrderCallBackEvent event = ringBuffer.get(sequence);
        event.setOrderSn("OrderCallBackEvent1234856RingBuffer");
        ringBuffer.publish(sequence);
    }
}

//https://my.oschina.net/u/3795437/blog/2873689